import time
from threading import Lock, current_thread
from .common_func.print_logger import PrintLogger


class UThreadLock:
    def __init__(self, lock_name="", logger=PrintLogger):
        self.lock = Lock()
        self.holder = "None"  # 锁持有人，填入获取到锁的进程名
        self.locked_count = 0  # 锁持有次数
        self.logger = logger
        if not lock_name:
            lock_name = f"thread_lock_{int(time.time())}"
        self.lock_name = lock_name
        self.logger.info(f"UThreadLock instance init done with name:{lock_name}")

    def release(self):
        """
        默认锁释放函数
        1.如果当前进程没有持有锁，给出警告并返回
        2.如果当前进程持有锁，则将锁持有次数减1
        3.如果当前进程锁持有次数为0,则释放锁
        :return:
        """
        cur_thread_name = current_thread().getName()

        if self.holder != cur_thread_name:
            self.logger.warning(f"{cur_thread_name} try to release lock:{self.lock_name} which is hold by {self.holder}")
            return

        self.locked_count -= 1
        self.logger.debug(f"{cur_thread_name}持有锁:{self.lock_name}计数减1,目前持有计数为:{self.locked_count}")
        if not self.locked_count:
            self.lock.release()
            self.holder = "None"
            self.logger.debug(f"{cur_thread_name}释放锁:{self.lock_name}")

    def acquire(self):
        """
        默认锁获取函数
        1.如果当前进程没有持有锁，调用lock.acquire，获取锁后，锁持有次数设置为初始的1
        2.如果当前进程持有锁，则将锁持有次数减1
        :return:
        """
        cur_thread_name = current_thread().getName()

        if self.holder != cur_thread_name:
            self.lock.acquire()
            # 获取到锁后，更新锁持有信息
            self.holder = cur_thread_name
            self.locked_count = 1
        else:
            self.locked_count += 1
        self.logger.debug(f"{cur_thread_name}获取锁：{self.lock_name}完成，目前持有次数：{self.locked_count}")

    def locked(self):
        return self.lock.locked()

    def __enter__(self):
        self.acquire()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.release()
